import email
import imaplib
import os
import datetime
from fetchemApp.models import *
from django.conf import settings
from email.parser import HeaderParser
from fetchemApp import chk_pdf
import sys
import threading
sys.stdout = sys.stderr

def month_conversion(t):
    month ={'Jan':1, 
            'Feb':2, 
            'Mar':3, 
            'Apr':4,
            'May':5,
            'Jun':6, 
            'Jul':7, 
            'Aug':8, 
            'Sep':9,
            'Oct':10,
            'Nov':11,
            'Dec':12
            }
    
    if type(t)==type(1):
        for word, num in month.items():
            if num==t:
                return word
    elif type(t)== type('string'):
        return month[t]

def get_name(header):
    k=header.items()
    spl1= k[3][1].split('@')
    return spl1  

def get_emailid(header):
    k=header.items()
    spl1= k[3][1]
    return spl1[1:-1] 
      
def checkdate(header):
    k= header.items()
    spl1 = k[1][1].split(';')
    spl2 = spl1[1].split(',')
    spl3 = spl2[1].split(' ')
    spl4 = spl3[4].split(':')
    dt = datetime.datetime(int(spl3[3]), int(month_conversion(spl3[2])), int(spl3[1]), int(spl4[0]), int(spl4[1]), int(spl4[2]))
    d= datetime.timedelta(hours=13,minutes=30)
    k = dt+d      
    return k
    
def func(userName, passwd, subject, after, before, course_id, course_no, course_object, assign_id, assign_object):
    path = os.path.join(settings.MEDIA_ROOT, 'Attachments/'+str(course_id)+'_'+str(course_no)+'/'+str(subject))
    detach_dir = '.'
    try:
        os.makedirs(path)
    except OSError as O:
        print O.strerror + "; " + O.filename
        pass
    
    if before.time()=='00:00:00':
        new_before = before
    else:
        new_before = before + datetime.timedelta(days=1)

    try:
        imapSession = imaplib.IMAP4_SSL('imap.gmail.com')
        typ, accountDetails = imapSession.login(userName, passwd)
        if typ != 'OK':
            #print 'Not able to sign in!'
            raise
        imapSession.create('INVALID')
        imapSession.select('Inbox', readonly = False)
        typ, data = imapSession.uid('search', None, '(SENTSINCE '+str(after.day)+'-'+str(month_conversion(after.month))+'-'+str(after.year)+' SENTBEFORE '+str(new_before.day)+'-'+str(month_conversion(before.month))+'-'+str(before.year)+' HEADER Subject '+subject+')')
        if typ != 'OK':
            #print 'Error searching Inbox.'
            raise
        print 'Mails matched: ' + str(len(data[0].split()))
        for msgId in data[0].split():
            attachment_flag=0
            try:
                flag=0
                for x in Submission.objects.filter(assignment_id = assign_id):
                    if x.EmailUID==int(msgId):
                        flag=1
                        print 'flag=1'
                        break
                    else:
                        continue
                
                if flag==1:
                    continue  
                
                #print 'msgID= '+msgId
                typ, messageParts = imapSession.uid('fetch',msgId, '(RFC822)')
                if typ != 'OK':
                    #print 'Error fetching mail.'
                    raise
            
                emailBody = messageParts[0][1]
                mail = email.message_from_string(emailBody)
                parser = HeaderParser()
                header = parser.parsestr(emailBody)
                email_id= str(get_emailid(header))
                stud_list = Student.objects.filter(Email = email_id)
                if len(stud_list)==1:
                    get_name(header) 
                    cd = checkdate(header)         
                    if cd <= before:
                        for part in mail.walk():
                            if part.get_content_maintype() == 'multipart':
                                continue
                            if part.get('Content-Disposition') is None:
                                continue
                            
                            fileName = part.get_filename()
                    
                            if bool(fileName):
                                attachment_flag=1
                                if fileName[-4:] == '.pdf':
                                    newFileName = str(get_name(header)[0][1:])+'_'+str(course_id)+'_'+str(assign_id)+'_'+str(get_name(header)[1][:-1])+'.pdf'
                                    filePath = os.path.join(detach_dir, path, newFileName)
                                    if not os.path.isfile(filePath) :
                                        #print fileName
                                        #print 'Attempting to write to ' + filePath
                                        fp = open(filePath, 'wb')
                                        fp.write(part.get_payload(decode=True))
                                        fp.close()
                                        Submission.objects.create(assignment=assign_object,ReceivedDateTime = cd, EmailUID= msgId, student = stud_list[0], Status='New', Filename=filePath)
                                    elif cd > Submission.objects.filter(Filename=filePath)[0].ReceivedDateTime :
                                        Submission.objects.filter(Filename=filePath)[0].delete()
                                        #print fileName
                                        fp = open(filePath, 'wb')
                                        fp.write(part.get_payload(decode=True))
                                        fp.close()
                                        Submission.objects.create(assignment=assign_object,ReceivedDateTime = cd, EmailUID= msgId, student = stud_list[0], Status='New', Filename=filePath)
                                else:
                                    print 'not a pdf' 
                                    T = threading.Thread(target=chk_pdf.pdfchk, kwargs={'stud_object': stud_list[0], 'course_object':course_object, 'assign_object': assign_object, 'type_of_prob': 'not_pdf'})
                                    T.start()
                                    #chk_pdf.pdfchk(stud_list[0], course_object, assign_object, 'not_pdf')
                                    copy_result = imapSession.uid('COPY', msgId, 'INVALID')
                                    if copy_result[0]=='OK':
                                        print 'moving'
                                        mov, data = imapSession.uid('STORE', msgId , '+FLAGS', '(\Deleted)')
                                        imapSession.expunge() 
                                        
            
            except:
                continue
            
            if attachment_flag==0 and flag!=1:
                print 'no attachment'
                T = threading.Thread(target=chk_pdf.pdfchk, kwargs={'stud_object': stud_list[0], 'course_object':course_object, 'assign_object': assign_object, 'type_of_prob': 'no_attachment'})
                T.start()
                copy_result = imapSession.uid('COPY', msgId, 'INVALID')
                if copy_result[0]=='OK':
                    print 'moving'
                    mov, data = imapSession.uid('STORE', msgId , '+FLAGS', '(\Deleted)')
                    imapSession.expunge()
                #chk_pdf.pdfchk(stud_list[0], course_object, assign_object, 'no_attachment')
        imapSession.close()
        imapSession.logout()
        return
            
    except Exception as e:
        pass
        #print 'Not able to download all attachments.' + e.strerr
        
def fetch(assign_object):
    subject_line = assign_object.SubjectLine
    after_date = assign_object.StartDateTime
    before_date = assign_object.EndDateTime
    username = assign_object.course.SubEmail
    password = assign_object.course.SubPassword
    assign_id = assign_object.id
    course_id = assign_object.course.id
    course_no = assign_object.course.CourseNo
    course_object = assign_object.course
    func(username, password, subject_line, after_date, before_date, course_id, course_no,course_object, assign_id, assign_object)
#fetch(Assignment.objects.get(pk=3))
